package conversion

import (
	"fmt"
	"osiris/logger"

	peer "github.com/libp2p/go-libp2p/core/peer"
	ma "github.com/multiformats/go-multiaddr"
)

// StrToMultiaddr 根据MutilAddr.String()返回的字符串生成对应的MutilAddr
//
//	@param str MultiAddr的字符串形式，对应MutilAddr.String()
//	@return ma.Multiaddr
//	@return error
func StrToMultiaddr(str string) (ma.Multiaddr, error) {
	addr, err := ma.NewMultiaddr(str)

	if err != nil {
		logger.Error(map[string]interface{}{fmt.Sprintf("[core] [Generate multiaddr] string %s", str): err.Error()})
		return nil, err
	}

	return addr, nil
}

// StrToPeerID 根据peer.ID.String()返回的字符串生成对应的peer.ID
//
//	@param str peer.ID的字符串形式，对应peer.ID.String()
//	@return peer.ID
//	@return error
func StrToPeerID(peerIDStr string) (peer.ID, error) {
	peerID, err := peer.Decode(peerIDStr)

	if err != nil {
		logger.Error(map[string]interface{}{fmt.Sprintf("[core] [Str to peer.ID] string %s", peerIDStr): err.Error()})
	}

	return peerID, err
}

// StrToPeerIDBytes 根据peer.ID.String()返回的字符串生成对应的peer.ID的字节数组
//
//	@param peerIDStr
//	@return []byte
//	@return error
func StrToPeerIDBytes(peerIDStr string) ([]byte, error) {
	peerID, err := StrToPeerID(peerIDStr)
	if err != nil {
		logger.Error(map[string]interface{}{fmt.Sprintf("[core] [Str to peer.ID Bytes] string %s", peerIDStr): err.Error()})
		return make([]byte, 0), err
	}

	return peerID.MarshalBinary()
}

func BytesToPeerID(peerIDBytes []byte) (peer.ID, error) {
	peerID := new(peer.ID)
	err := peerID.UnmarshalBinary(peerIDBytes)
	return *peerID, err
}

// MultiaddrsToStrings 将ma.Multiaddr数组转化为字符串数组，用于PeerDto生成
//
//	@param addrs ma.Multiaddr数组
//	@return []string
func MultiaddrsToStrings(addrs []ma.Multiaddr) []string {
	var array []string
	for _, addr := range addrs {
		array = append(array, addr.String())
	}
	return array
}

// StringsToMultiaddrs 将字符串数组转化为ma.Multiaddr数组
//
//	@param strings
//	@return []ma.Multiaddr
//	@return error 第一个出现的错误
func StringsToMultiaddrs(strings []string) ([]ma.Multiaddr, error) {
	var array []ma.Multiaddr
	for _, str := range strings {
		addr, err := StrToMultiaddr(str)
		if err == nil {
			array = append(array, addr)
		} else {
			return array, err
		}
	}
	return array, nil
}
